class WS {
	constructor(url) {
		if (!url) {
		      throw new Error('websocket url is invalid')
		    }
		this.reconnectTimer = null // 断线重连定时器
		this.heartbeatTimer = null // 心跳检测定时器
		this.isAlive = false // 是否活着
		this.ownCloseStatus = false // 是否主动断开
		
		this.url = url
		this.retry = 5 //重连次数
		this.reconnectWait = 5 * 1000 // 重连等待时间(单位秒)
		this.heartBeatWait = 25 * 1000 // 心跳检测间隔
		this.isHeartBeat = true //是否打开心跳检测
		this.data = 'ping'
		this.isCreate = false // WebSocket 是否创建成功
		this.socketExamples = null // websocket实例

		this.initSocket()
	}
 
	// 初始化websocket连接
	initSocket() {
		console.log("初始化WS");
		const _this = this
		this.socketExamples = uni.connectSocket({
			url: _this.url,
			success: (res) => {
				_this.isCreate = true
				console.log(res,_this.isCreate,'--------')
				//#ifdef APP-PLUS
				this.createSocket()
				//#endif
			},
			fail: (rej) => {
				console.error(rej)
				_this.isCreate = false
			}
		})
		//#ifdef H5
		this.createSocket()
		//#endif
	}
 
	// 创建websocket连接
	createSocket() {
		if (this.isCreate) {
			// 监听 WebSocket 连接打开事件
			try {
				this.socketExamples.onOpen(() => {
					this.isAlive = true
					
					const params = {
						type: 100,
						data: {
							from: uni.getStorageSync('userId'),
							token: uni.getStorageSync('satoken'),
							serviceProviderNo: uni.getStorageSync('serviceProviderNo')
						}
					}
					this.socketExamples.send({
						data: JSON.stringify(params),
						async success() {
							console.log("初始化成功");
						},
					});
					
					// 用户在聊天室断开重新创建会话
					// if(uni.getStorageSync('userCreateNewSessionFlag')) {
					// 	let params = {
					// 		type: 5,
					// 		data: {
					// 			to: uni.getStorageSync('otherId')
					// 		}
					// 	}
					// 	this.socketExamples.send({
					// 		data: JSON.stringify(params),
					// 		async success() {
					// 			console.log("创建会话成功");
					// 		},
					// 	});
					// }
					// uni.setStorageSync('userCreateNewSessionFlag',false)
					
					// 打开心跳检测
					if(this.isHeartBeat) {
						this.heartbeatCheck()
					}
				})
				// 监听 WebSocket 接受到服务器的消息事件
				this.socketExamples.onMessage((res) => {
					let params = JSON.parse(res.data)
					if(res.data.indexOf("pong") > -1)return
					if(params.type === 9) {
						uni.$emit('expertList',params)
					}
					if(params.type === 2) {
						uni.$emit('update',params.data.from)
					}
					uni.$emit('WSMSG', res)
				})
				// 监听 WebSocket 连接关闭事件
				this.socketExamples.onClose(() => {
					console.log('WebSocket 关闭了')
					this.isAlive = false
					if(!this.ownCloseStatus) {
						this.reconnect()
					}
				})
				// 监听 WebSocket 错误事件
				this.socketExamples.onError((res) => {
					console.log('WebSocket 出错了')
					if(this.ownCloseStatus) {
						this.reconnect()
					}
					this.isAlive = false
				})
			} catch (error) {
				console.warn(error)
			}
		} else {
			console.warn('WebSocket 初始化失败!')
		}
	}
 
	// 发送消息
	sendMsg(value) {
		const _this = this
		const param = JSON.stringify(value)
		return new Promise((resolve, reject) => {
			if(!_this.socketExamples) return
			this.socketExamples.send({
				data: param,
				success() {
					// console.log('消息发送成功',param)
					resolve(true)
				},
				fail(error) {
					// _this.initSocket()
					// console.log('消息发送失败',`_this.isAlive=${_this.isAlive} _this.isCreate=${_this.isCreate}`)
					reject(error)
				}
			})
		})
	}
 
	// 开启心跳检测
	heartbeatCheck() {
		this.heartbeatTimer = setInterval(() => {
			this.sendMsg(this.data)
		}, this.heartBeatWait)
	}
 
	// 重新连接
	reconnect() {
		// 如果不是人为关闭的话，进行重连
		this.reconnectTimer = setTimeout(() => {
			console.log(this.retry);
			if(this.retry>0) {
				this.retry--
				this.initSocket()
			}
		}, this.reconnectWait)
	}
 
	// 关闭 WebSocket 连接
	closeSocket(reason = '关闭') {
		const _this = this
		this.socketExamples.close({
			reason,
			success() {
				_this.data = null
				_this.isCreate = false
				_this.ownCloseStatus = true
				_this.socketExamples = null
				clearInterval(_this.heartbeatTimer)
				clearTimeout(_this.reconnectTimer)
				console.log('关闭 WebSocket 成功')
			},
			fail() {
				console.log('关闭 WebSocket 失败')
			}
		})
	}
}
 
export default WS